package top.went.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.went.db.dao.*;
import top.went.db.mapper.InStorageMapper;
import top.went.db.mapper.OutStorageMapper;
import top.went.db.mapper.WareHouseMapper;
import top.went.db.mapper.WpDetailWapper;
import top.went.exception.NotFoundException;
import top.went.exception.ServiceException;
import top.went.pojo.*;
import top.went.vo.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 仓库
 */
@Service
@Transactional(value = "transactionManager",rollbackFor = ServiceException.class)
public class WareHouseService {
    @Autowired
    private WareHouseDao wareHouseDao;
    @Autowired
    private WareHouseMapper wareHouseMapper;
    @Autowired
    private WareHouseNumberDao numberDao;
    @Autowired
    private WareHouseDetailDao wareHouseDetailDao;
    @Autowired
    private ProductService productService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OutStorageMapper outStorageMapper;
    @Autowired
    private InStorageMapper inStorageMapper;
    @Autowired
    private InStorageDao inStorageDao;
    @Autowired
    private OutStorageDao outStorageDao;
    @Autowired
    private WpDetailWapper wpDetailWapper;

    /** 表格排序*/
    private static Map<String,String> map = new HashMap<>();
    static {
        map.put("wpullName","wpull_Name");
        map.put("wpullDate","wpull_date");
        map.put("wpullStatus","wpull_status");
        map.put("orderName","orderName");
        map.put("outNumber","out_number");
        map.put("inNumber","in_number");
        map.put("wdExecute","wd_execute");
        map.put("wdState","wd_state");
        map.put("wdType","wd_type");
        map.put("productName","product_name");
        map.put("cusName","cus_name");
    }

    /**
     * 添加新的仓库
     * @param name
     * @return
     * @throws ServiceException
     */
    public boolean addWareHouse(String name) throws ServiceException {
        try {
            wareHouseDao.save(new WarehouseEntity(name));
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("添加仓库失败");
        }
        return true;
    }

    /**
     * 修改仓库名称
     * @param id
     * @param name
     * @return
     * @throws NotFoundException
     * @throws ServiceException
     */
    public boolean modifyWareHouseName(Long id, String name) throws NotFoundException, ServiceException {
        WarehouseEntity warehouseEntity = loadWareHouse(id);
        if (warehouseEntity.getWhName().equals(name))
            throw new ServiceException("仓库信息未更改");
        warehouseEntity.setWhName(name);
        try {
            wareHouseDao.save(warehouseEntity);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("仓库名称更改失败");
        }
        return true;
    }

    /**
     * 删除仓库
     * @param id
     * @return
     * @throws NotFoundException
     * @throws ServiceException
     */
    public boolean deleteWareHouse(Long id) throws NotFoundException, ServiceException {
        WarehouseEntity warehouseEntity = loadWareHouse(id);
        if (numberDao.countAllProduct(warehouseEntity.getWhId()) > 0)
            throw new ServiceException("该仓库下存在产品库存");
        warehouseEntity.setLogicDelete(true);
        try {
            wareHouseDao.save(warehouseEntity);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("删除仓库失败");
        }
        return true;
    }

    /**
     * 普通模糊查询
     * @return
     */
    public PageEntity<WhNumberEntity> findAllSimpleSearch(String text, Integer page, Integer size){
        Page<WhNumberEntity> page1 = PageHelper.startPage(page,size);
        wareHouseMapper.findAllSimpleSearch(text);
        return new PageEntity<>(page1.getTotal(), page1.getResult());
    }

    /**
     * 高级查询
     * @return
     */
    @Transactional(value = "transactionManager-my",rollbackFor = ServiceException.class)
    public PageEntity<WhNumberEntity> findAllSeniorSearch(WareHouse wareHouse, Integer page, Integer size) {
        Page<WhNumberEntity> page1 = PageHelper.startPage(page,size);
       wareHouseMapper.findAllSeniorSearch(wareHouse);
        return new PageEntity<>(page1.getTotal(), page1.getResult());
    }

    /**
     * 加载仓库
     * @param id
     * @return
     * @throws NotFoundException
     */
    public WarehouseEntity loadWareHouse(Long id) throws NotFoundException {
        WarehouseEntity warehouseEntity = wareHouseDao.findOne(false,id);
        if (warehouseEntity == null)
            throw new NotFoundException("该仓库不存在");
        return warehouseEntity;
    }

    /**
     * 加载仓库在库记录
     * @param id
     * @return
     * @throws NotFoundException
     */
    public List<Map<String,Object>> load(Long id) throws NotFoundException {
        ProductFormatEntity formatEntity = productService.load(id.intValue());
        List<WhNumberEntity> whNumberEntities = numberDao.loadAll(formatEntity.getPfId(),false);
        List<Map<String,Object>> datas = new ArrayList<>();
        for (WhNumberEntity whNumberEntity : whNumberEntities) {
            Map<String,Object> map = new HashMap<>();
            map.put("name",whNumberEntity.getTbWarehouseByWhId().getWhName());
            map.put("number",whNumberEntity.getWnNumber());
            datas.add(map);
        }
        return datas;
    }

    /**
     * 修改产品库存
     * @param product
     * @param wareHouse
     * @param number
     * @return
     */
    public boolean modifyWareHouseNumber(Integer product,Long wareHouse,Long number) throws NotFoundException, ServiceException {
        ProductFormatEntity formatEntity = productService.load(product.intValue());
        WarehouseEntity warehouseEntity = loadWareHouse(wareHouse);
        WhNumberEntity whNumberEntity = numberDao.findOne(product,wareHouse);
        if (whNumberEntity == null){
            if (number < 0)
                throw new ServiceException("产品库存不允许为负数");
            whNumberEntity = new WhNumberEntity(number,formatEntity,warehouseEntity);
        }else
            whNumberEntity.setWnNumber(whNumberEntity.getWnNumber() + number);
        try {
            numberDao.save(whNumberEntity);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("产品库存修改失败");
        }
        return true;
    }

    /**
     * 加载所有仓库
     * @return
     */
    public List<WarehouseEntity> loadAll() {
        return wareHouseDao.loadAll(false);
    }

    /**
     * 加载所有出库单
     * @param search
     * @return
     */
    public PageEntity<OutStorageVo> findOutAll(OutStorageSearch search) {
        if (search == null)
            return new PageEntity<OutStorageVo>(0L,null);
        String order = search.getPage().getSort(map);
        if (order.length() <=0)
            order = "wpull_id desc";
        Page<OutStorageVo> page1 = PageHelper.startPage(search.getPage().getPage(),search.getPage().getSize(),
                order);
        outStorageMapper.findAll(search);
        System.out.println(page1);
        return new PageEntity<>(page1.getTotal(), page1.getResult());
    }

    /**
     * 加载所有入库单
     * @param search
     * @return
     */
    public PageEntity<InStorageVo> findINAll(InStorageSearch search) {
        if (search == null)
            return new PageEntity<InStorageVo>(0L,null);
        String order = search.getPage().getSort(map);
        if (order.length() <=0)
            order = "wp_id desc";
        Page<InStorageVo> page1 = PageHelper.startPage(search.getPage().getPage(),search.getPage().getSize(),
                order);
        inStorageMapper.findAll(search);
        System.out.println(page1);
        return new PageEntity<>(page1.getTotal(), page1.getResult());
    }

    /**
     * 修改出库单
     * @param whPullEntity
     * @throws NotFoundException
     * @throws ServiceException
     */
    public void modifyOutbound(WhPullEntity whPullEntity) throws NotFoundException, ServiceException {
        WhPullEntity w = loadOut(whPullEntity.getWpullId());
        if (w.getWpullStatus() != 0)
            throw new ServiceException("只有执行未出库可以修改");
        boolean changeWh = false;
        if (w.getTbWarehouseByWhId().getWhId() != whPullEntity.getTbWarehouseByWhId().getWhId())
            changeWh = true;
        modifyWhpullData(w,whPullEntity);
        List<WpDetailEntity> wpDetailEntities = wareHouseDetailDao.loadAll(w.getWpullId(),0);
        try {
            if (wpDetailEntities != null && changeWh)
                for (WpDetailEntity wpDetailEntity : wpDetailEntities) {
                    wpDetailEntity.setTbWarehouseByWhId(w.getTbWarehouseByWhId());
                    System.out.println("我是分割线"+wpDetailEntity.getTbWarehouseByWhId().getWhName());
                }
            wareHouseDetailDao.save(wpDetailEntities);
            outStorageDao.save(w);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("修改出库单失败");
        }
    }

    /**
     * 更改出库单数据
     * @param w
     * @param whPullEntity
     * @throws NotFoundException
     */
    private void modifyWhpullData(WhPullEntity w, WhPullEntity whPullEntity) throws NotFoundException {
        w.setWpullName(whPullEntity.getWpullName());
        if (!w.getTbWarehouseByWhId().getWhId().equals(whPullEntity.getTbWarehouseByWhId().getWhId()))
            w.setTbWarehouseByWhId(loadWareHouse(whPullEntity.getTbWarehouseByWhId().getWhId()));
        w.setWpullDate(whPullEntity.getWpullDate());
        w.setWpullOther(whPullEntity.getWpullOther());
        if (whPullEntity.getTbUserByUserId()!= null &&whPullEntity.getTbUserByUserId().getUserId()!= null)
            w.setTbUserByUserId(whPullEntity.getTbUserByUserId());
    }

    /**
     * 加载出库单
     * @param wpullId
     * @return
     * @throws NotFoundException
     */
    public WhPullEntity loadOut(Integer wpullId) throws NotFoundException {
        WhPullEntity whPullEntity = outStorageDao.loadOne(false,wpullId);
        if (whPullEntity == null)
            throw new NotFoundException("该出库单不存在");
        return whPullEntity;
    }

    /**
     * 加载出库单
     * @param id
     * @return
     * @throws NotFoundException
     */
    public OutStorageVo loadOneOut(Integer id) throws NotFoundException {
        OutStorageVo outStorageVo = outStorageMapper.load(id);
        if (outStorageVo == null)
            throw new NotFoundException("该出库单不存在");
        return outStorageVo;
    }

    /**
     * 添加出库单
     * @param whPullEntity
     * @throws NotFoundException
     * @throws ServiceException
     */
    public void addOut(WhPullEntity whPullEntity) throws NotFoundException, ServiceException {
       if (whPullEntity.getTbOrderByOrderId() != null)
           whPullEntity.setTbOrderByOrderId(orderService.load(whPullEntity.getTbOrderByOrderId().getOrderId().longValue()));
       else //加载采购单
           whPullEntity.setTbReturnGoodsByRgId(null);
       whPullEntity.setTbWarehouseByWhId(loadWareHouse(whPullEntity.getTbWarehouseByWhId().getWhId()));
       //加载经手人
       whPullEntity.setTbUserByUserId(null);
       //加载执行人
       if (whPullEntity.getTbUserByTbUserId() != null)
           whPullEntity.setTbUserByTbUserId(null);
       whPullEntity.setLogicDelete(false);
       whPullEntity.setWpullStatus(0);
       try {
           outStorageDao.save(whPullEntity);
       }catch (Exception e){
           e.printStackTrace();
           throw new ServiceException("添加出库单失败");
       }
    }



    /**
     * 删除出库单
     * @param intValue
     * @return
     * @throws NotFoundException
     * @throws ServiceException
     */
    public boolean deleteOut(int intValue) throws NotFoundException, ServiceException {
        WhPullEntity whPullEntity = loadOut(intValue);
        if (whPullEntity.getWpullStatus() != 0)
            throw new ServiceException("只有未出库订单可以删除");
        try {
            wareHouseDetailDao.deleteByOut(intValue,0,-1);
            whPullEntity.setLogicDelete(true);
            outStorageDao.save(whPullEntity);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("删除出库单失败");
        }
        return true;
    }

    /**
     * 批量删除出库单
     * @param ids
     * @return
     * @throws NotFoundException
     * @throws ServiceException
     */
    public boolean deleteOutAll(Integer[] ids) throws NotFoundException, ServiceException {
        for (Integer id : ids) {
            deleteOut(id);
        }
        return true;
    }

    /**
     * 加载所有库存流水
     * @param search
     * @return
     */
    public PageEntity<WpDetailVo> findDetailAll(WpDeatilSearch search) {
        if (search == null)
            return new PageEntity<WpDetailVo>(0L,null);
        String order = search.getPage().getSort(map);
        if (order.length() <=0)
            order = "wd_id desc";
        Page<WpDetailVo> page1 = PageHelper.startPage(search.getPage().getPage(),search.getPage().getSize(),
                order);
        wpDetailWapper.findAll(search);
        System.out.println(page1);
        return new PageEntity<>(page1.getTotal(), page1.getResult());
    }

    /**
     * 修改入库单
     * @param whPutEntity
     * @throws ServiceException
     * @throws NotFoundException
     */
    public void modifyInbound(WhPutEntity whPutEntity) throws ServiceException, NotFoundException {
        WhPutEntity w = loadIn(whPutEntity.getWpId());
        if (w.getWpStatus() != 0)
            throw new ServiceException("只有执行入出库可以修改");
        boolean changeWh = false;
        if (w.getTbWarehouseByWhId().getWhId() != whPutEntity.getTbWarehouseByWhId().getWhId())
            changeWh = true;
        modifyWhputData(w,whPutEntity);
        List<WpDetailEntity> wpDetailEntities = wareHouseDetailDao.loadAll(w.getWpId(),1);
        try {
            if (wpDetailEntities != null && changeWh)
                for (WpDetailEntity wpDetailEntity : wpDetailEntities) {
                    wpDetailEntity.setTbWarehouseByWhId(w.getTbWarehouseByWhId());
                }
            wareHouseDetailDao.save(wpDetailEntities);
            inStorageDao.save(w);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("修改入库单失败");
        }
    }

    /**
     * 修改入库单数据
     * @param w
     * @param whPutEntity
     */
    private void modifyWhputData(WhPutEntity w, WhPutEntity whPutEntity) throws NotFoundException {
        w.setWpName(whPutEntity.getWpName());
        w.setWpOther(whPutEntity.getWpOther());
        w.setWpDate(whPutEntity.getWpDate());
        if (!w.getTbWarehouseByWhId().getWhId().equals(whPutEntity.getTbWarehouseByWhId().getWhId()))
            w.setTbWarehouseByWhId(loadWareHouse(whPutEntity.getTbWarehouseByWhId().getWhId()));
    }

    /**
     * 加载入库单
     * @param wpId
     * @return
     * @throws NotFoundException
     */
    public WhPutEntity loadIn(Integer wpId) throws NotFoundException {
        WhPutEntity whPuuEntity = inStorageDao.loadOne(false,wpId);
        if (whPuuEntity == null)
            throw new NotFoundException("入库单不存在");
        return whPuuEntity;
    }

    /**
     * 添加入库单
     * @param whPutEntity
     * @throws NotFoundException
     * @throws ServiceException
     */
    public void addIn(WhPutEntity whPutEntity) throws NotFoundException, ServiceException {
        whPutEntity.setTbWarehouseByWhId(loadWareHouse(whPutEntity.getTbWarehouseByWhId().getWhId()));
        //加载经手人
        whPutEntity.setTbUserByUserId(null);
        //加载执行人
        if (whPutEntity.getTbUserByTbUserId() != null)
            whPutEntity.setTbUserByTbUserId(null);
        whPutEntity.setLogicDelete(false);
        whPutEntity.setWpStatus(0);
        try {
            inStorageDao.save(whPutEntity);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("添加出库单失败");
        }
    }

    /**
     * 加载入库单
     * @param intValue
     * @return
     */
    public InStorageVo loadOneIn(int intValue) throws NotFoundException {
        InStorageVo inStorageVo = inStorageMapper.load(intValue);
        if (inStorageVo == null)
            throw new NotFoundException("该入库单不存在");
        return inStorageVo;
    }

    /**
     * 删除入库单
     * @param intValue
     */
    public void deleteIn(int intValue) throws ServiceException, NotFoundException {
        WhPutEntity whPutEntity = loadIn(intValue);
        if (whPutEntity.getWpStatus() != 0)
            throw new ServiceException("只有未出库订单可以删除");
        try {
            wareHouseDetailDao.deleteByOut(intValue,1,-1);
            whPutEntity.setLogicDelete(true);
            inStorageDao.save(whPutEntity);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("删除出库单失败");
        }
    }

    /**
     * 批量删除入库单
     * @param ids
     * @throws NotFoundException
     * @throws ServiceException
     */
    public void deleteInAll(Integer[] ids) throws NotFoundException, ServiceException {
        for (Integer id : ids) {
            deleteIn(id);
        }
    }


}
